package cn.practice.chat.service.impl;

import cn.practice.chat.entity.ChatGroup;
import cn.practice.chat.entity.ChatGroupUser;
import cn.practice.chat.entity.ChatList;
import cn.practice.chat.entity.ChatRecord;
import cn.practice.chat.enums.ChatTypeEnum;
import cn.practice.chat.lang.RedisConst;
import cn.practice.chat.mapper.ChatGroupMapper;
import cn.practice.chat.mapper.ChatListMapper;
import cn.practice.chat.mapper.ChatRecordMapper;
import cn.practice.chat.request.chat.ChatGroupRequest;
import cn.practice.chat.request.chat.ChatRequest;
import cn.practice.chat.response.chat.ChatListResponse;
import cn.practice.chat.response.chat.ChatRecordResponse;
import cn.practice.chat.response.user.LoginUser;
import cn.practice.chat.service.ChatGroupUserService;
import cn.practice.chat.service.ChatListService;
import cn.practice.chat.utils.RedisUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

import static cn.practice.chat.lang.Const.defaultGroupImage;

/**
 * <p>
 * 最近聊天的人 服务实现类
 * </p>
 *
 * @author zhuutao
 * @since 2022-10-31
 */
@Slf4j
@Service
public class ChatListServiceImpl extends ServiceImpl<ChatListMapper, ChatList> implements ChatListService {

    @Autowired
    private ChatListMapper chatListMapper;

    @Autowired
    private ChatRecordMapper chatRecordMapper;

    @Autowired
    private RedisUtil redisUtil;


    @Autowired
    private ChatGroupMapper chatGroupMapper;

    @Autowired
    private ChatGroupUserService chatGroupUserService;

    @Override
    public List<ChatListResponse> chatList(LoginUser loginUser) {
        String key = RedisConst.CHAT_LIST_KEY + loginUser.getUserId();
        // 查询redis缓存 如果没有重新差一次，存入redis
        Map<String, Object>  chatMap =  redisUtil.hmget(key);
        List<ChatListResponse> responseList = null;
        if(CollectionUtils.isEmpty(chatMap)){
            // 查询最近联系人列表
            responseList = chatListMapper.chatList(loginUser.getUserId());
            log.info("获取聊天列表，responseList={}", responseList);
            if(!CollectionUtils.isEmpty(responseList)){
                // 查询聊天记录 进行封装
                List<String> messageIds = responseList.stream().map(v->v.getMessageId()).collect(Collectors.toList());
                List<ChatRecordResponse> chatRecordList = chatListMapper.recordListByMessageIdList(messageIds);
                log.info("获取聊天记录，总数量={}", chatRecordList.size());
                if(!CollectionUtils.isEmpty(chatRecordList)){
                    // 判断是不是自己发的消息
                    for(ChatRecordResponse record:chatRecordList){
                        if(loginUser.getUserId().equals(record.getSenderId())){
                            record.setSelf(Boolean.TRUE);
                        }else{
                            record.setSelf(Boolean.FALSE);
                        }
                    }
                    List<ChatRecordResponse> childrenList = null;
                    for(ChatListResponse chatResponse : responseList){
                        String msgId = chatResponse.getMessageId();
                        childrenList = chatRecordList.stream().filter(c->msgId.equals(c.getMessageId()))
                                .collect(Collectors.toList());
                        if(!CollectionUtils.isEmpty(childrenList)){
                            chatResponse.setChatRecordList(childrenList);
                        }else {
                            if(chatResponse.getType().equals(ChatTypeEnum.SingleChat.getType())){
                                // 添加默认消息
                                List<ChatRecordResponse> defaultRecords = new ArrayList<>();
                                ChatRecordResponse defaultRecord = new ChatRecordResponse();
                                defaultRecord.setRecordId(1);
                                defaultRecord.setSelf(false);
                                defaultRecord.setSenderId(chatResponse.getFriendId());
                                defaultRecord.setImageUrl(chatResponse.getImageUrl());
                                defaultRecord.setMessageId(chatResponse.getMessageId());
                                defaultRecord.setNick(chatResponse.getNick());
                                defaultRecord.setContent("已经置顶聊天，可以给我发信息啦!");
                                defaultRecords.add(defaultRecord);
                                defaultRecord.setReceiverId(loginUser.getUserId());
                                chatResponse.setChatRecordList(defaultRecords);
                            }
                        }
                    }
                }
                // 缓存到redis
                Map<String, Object> map = new ConcurrentHashMap<>();
                for(ChatListResponse response:responseList){
                    map.put(response.getFriendId().toString(), response);
                }
                //redisUtil.hmset(key, map, RedisConst.CHAT_LIST_KEY_TIMEOUT);
            }
            return responseList;
        }
        log.info("chatMap:{}",chatMap);
        responseList = new ArrayList<>();
        for (Map.Entry<String, Object> m :chatMap.entrySet()){
            Object obj = m.getValue();
            ChatListResponse response = JSONObject.parseObject(JSONObject.toJSONString(obj), ChatListResponse.class);
            responseList.add(response);
        }
        return responseList;
    }



    @Override
    public void createUserChat(ChatRequest chatRequest, LoginUser loginUser) {
        String key = RedisConst.CHAT_LIST_KEY + loginUser.getUserId();
        LambdaQueryWrapper<ChatList> chatListQuery = new LambdaQueryWrapper<>();
        chatListQuery.eq(ChatList::getUserId, loginUser.getUserId());
        chatListQuery.eq(ChatList::getChatUserId, chatRequest.getSenderId());
        chatListQuery.eq(ChatList::getType, chatRequest.getType());

        ChatList chat = chatListMapper.selectOne(chatListQuery);
        if(chat == null){
            List<Integer> idList= new ArrayList<>();
            idList.add(loginUser.getUserId());
            List<String> strings = chatListMapper.selectMessageIdList(idList);
            // 修改排序信息
            if(!CollectionUtils.isEmpty(strings)){
                chatListMapper.updateSerialNo(strings);
            }
            redisUtil.del(key);
            // 增加联系人
            ChatList insertInfo = new ChatList();
            insertInfo.setUserId(loginUser.getUserId());
            insertInfo.setChatUserId(chatRequest.getSenderId());
            insertInfo.setType(ChatTypeEnum.SingleChat.getType());
            insertInfo.setMessageId(chatRequest.getMessageId());
            insertInfo.setSerialNo(1);
            chatListMapper.insert(insertInfo);
            //增加一条默认消息
            ChatRecord chatRecord = new ChatRecord();
            chatRecord.setMessageId(chatRequest.getMessageId());
            chatRecord.setSenderId(chatRequest.getSenderId());
            chatRecord.setMessageContent(chatRequest.getContent());
            chatRecord.setReceiverId(loginUser.getUserId());
            chatRecord.setSendTime(LocalDateTime.now());
            chatRecordMapper.insert(chatRecord);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ChatListResponse createChatGroup(ChatGroupRequest chatGroupRequest, LoginUser loginUser) {
        // 所有的群成员
        List<Integer> idList = chatGroupRequest.getIdList();
        idList.add(loginUser.getUserId());

        // 创建聊天群
        ChatGroup  chatGroup = new ChatGroup();
        String messageId = UUID.randomUUID().toString().replace("-","");
        chatGroup.setGroupName(chatGroupRequest.getGroupName());
        chatGroup.setMessageId(messageId);
        chatGroup.setImageUrl(defaultGroupImage);
        chatGroup.setCreateTime(LocalDateTime.now());
        chatGroup.setCreateUser(loginUser.getUserId());
        chatGroupMapper.insert(chatGroup);

        List<ChatGroupUser> groupUsers = new ArrayList<>();
        for (Integer userId:idList){
            ChatGroupUser  chatGroupUser = new ChatGroupUser();
            chatGroupUser.setGroupId(chatGroup.getId());
            chatGroupUser.setCreateTime(LocalDateTime.now());
            chatGroupUser.setUserId(userId);
            groupUsers.add(chatGroupUser);
        }
        chatGroupUserService.saveBatch(groupUsers);

        List<String> strings = chatListMapper.selectMessageIdList(idList);
        // 修改排序信息
        if(!CollectionUtils.isEmpty(strings)){
            chatListMapper.updateSerialNo(strings);
        }
        // 增加聊天信息
        List<ChatList> chatLists = new ArrayList<>();
        for (Integer userId:idList){
            ChatList chatList = new ChatList();
            chatList.setGmtCreate(LocalDateTime.now());
            chatList.setUserId(userId);
            chatList.setChatUserId(chatGroup.getId());
            chatList.setType(ChatTypeEnum.GroupChat.getType());
            chatList.setMessageId(messageId);
            chatList.setSerialNo(1);
            chatLists.add(chatList);
        }
        this.saveBatch(chatLists);

        ChatListResponse response = new ChatListResponse();
        response.setFriendId(chatGroup.getId());
        response.setMessageId(chatGroup.getMessageId());
        response.setNick(chatGroup.getGroupName());
        response.setImageUrl(chatGroup.getImageUrl());
        response.setSerialNo(1);
        response.setType(ChatTypeEnum.GroupChat.getType());
        response.setFriendName(chatGroup.getGroupName());
        return response;
    }
}
